#include <atomic>
#include <chrono>
#include <iostream>
#include <string>
#include <sys/epoll.h>
#include <thread>
#include <vector>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h> 
#include <fcntl.h> 
#include <sys/types.h>
#include <unistd.h>		/* read */

using namespace std;

class AcEncoder
{
    public:
        void StreamingLoop( int x );
        void EncoderYUV();
};

void AcEncoder::StreamingLoop( int x )
{
    while (true)
    {
        sleep(x);
        std::cout << "yuv->h264" << std::endl;
    }
}

void AcEncoder::EncoderYUV()
{
    int y = 1;

    /*
     * error: invalid use of non-static member function ‘void AcEncoder::StreamingLoop(int)’ 
     * 无效使用非静态成员函数 
     *
     * 报错原因：因为没有类对象，也就是没有类的实例化
     */

    // std::thread enc1( StreamingLoop, y );     /* error */
                                
    /*
     * 在 C++ 中，成员函数有一个隐含的第一个参数绑定(bind)到 this。创建线程时，必须传递this指针。
     * 还必须使用类名来限定成员函数。
     *
     * 这种情况下正确的线程构造函数如下所示:
     */
    
    std::thread enc1( &AcEncoder::StreamingLoop, this, y );


    /*
     * 也可以将 lambda 传递给线程构造函数:
     */ 
    std::thread enc2([this, y] // capture the this pointer and y by value
    {
        this->StreamingLoop(y);
    });

    
    /* captures everything (including this) by reference, captures a copy of y
     * becuase y coud go out of scope and be destroyed while the thread could 
     * continue running (even though in this case that won't happen because the join is in the same scope
     *
     * 通过引用捕获所有内容（包括此内容），捕获y的副本，
     * 因为y可能超出范围并在线程可以继续运行时被销毁（即使在这种情况下，
     * 因为联接在同一范围内，所以不会发生这种情况
     */
   
    std::thread t1([&,y]() { StreamingLoop(y); });   

    /* Of course, if you capture this then you don't need to mention it in the body of the lambda and 
     * without parameters needed we can remove the () which simplifies to:
     *
     * 当然，如果你捕捉到了这个，那么你就不需要在lambda的主体中提到它，并且在不需要参数的情况下，可以删除()，它简化为：
     */     
    std::thread t2([this,y] { StreamingLoop(y); }); 

    enc1.join();
    enc2.join();
    t1.join();
    t2.join();
}

int main()
{
    AcEncoder en;

    en.EncoderYUV();

    return 0;
}




